﻿using PEUtils;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace NavPlus
{
    public abstract class BaseNavigation
    {
        protected NavGridLogic m_StartGrid;
        protected NavGridLogic m_EndGrid;

        // 等待检测的队列
        protected PriorityQueue<NavGridLogic> m_OpenQue = new PriorityQueue<NavGridLogic>();

        // 搜索完成列表
        protected List<NavGridLogic> m_CloseLst = new List<NavGridLogic>();

        // 路径存储列表
        protected List<NavGridLogic> m_PathLst = new List<NavGridLogic>();

        public async Task<List<NavGridLogic>> CalcPath(NavGridLogic startPoint, NavGridLogic endPoint)
        {
            m_StartGrid = startPoint;
            m_EndGrid = endPoint;
            m_OpenQue.Clear();
            m_CloseLst.Clear();
            m_PathLst.Clear();
            m_StartGrid.SumDistance = 0;

            m_OpenQue.Enqueue(m_StartGrid);

            while (m_OpenQue.Count > 0)
            {
                if (m_OpenQue.Contains(m_EndGrid))
                {
                    m_PathLst = GetPathGridLst();
                    break;
                }
                    

                NavGridLogic currGrid = m_OpenQue.Dequeue(); 
                if (!m_CloseLst.Contains(currGrid))
                    m_CloseLst.Add(currGrid);

                // 遍历邻居节点
                for (int i = 0; i < currGrid.m_NeighborGrids.Count; i++)
                {
                    NavGridLogic neighborGrid = currGrid.m_NeighborGrids[i];
                    await Task.Delay(Launcher.Instance.SearchInterval);
                    DetectNeighborGrid(currGrid, neighborGrid);
                }
            }
            return m_PathLst ;
        }

        protected abstract void DetectNeighborGrid(NavGridLogic detectGrid, NavGridLogic neighborGrid);

        protected List<NavGridLogic> GetPathGridLst()
        {
            List<NavGridLogic> lst = new List<NavGridLogic>();
            NavGridLogic currGrid = m_EndGrid;
            while (currGrid.PreGrid != null)
            {
                lst.Insert(0, currGrid);
                currGrid = currGrid.PreGrid;
            }
            return lst;
        }
    }
}
